package com.neusoft.neuiotms.dcvm.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.neusoft.bizcore.cache.caching.CacheService;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.neuiotms.dcvm.bean.AttrBean;
import com.neusoft.neuiotms.dcvm.bean.LocationCiBean;
import com.neusoft.neuiotms.dcvm.bean.StandardCiBean;
import com.neusoft.neuiotms.dcvm.repository.ModelRepository;
import com.neusoft.neuiotms.dcvm.service.AssetService;
import com.neusoft.neuiotms.dcvm.service.LocationService;
import com.neusoft.neuiotms.dcvm.service.StatisticService;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.constants.CmdbSynConstants;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.model.RackUnitUsage;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.model.enums.RackTypeStatus;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.respository.RackUnitUsageRepository;
import com.neusoft.neuiotms.dcvm.utils.CmdbApi;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class StatisticServiceImpl implements StatisticService {

    @Autowired
    private ModelRepository modelRepository;
    @Autowired
    private LocationService locationService;
    @Autowired
    private RestTemplate restTemplate;
    @Value("${cmdb.proxy.target-url}")
    private String cmdbServiceUrl;
    @Autowired
    private AssetService cmdbMicroService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private RackUnitUsageRepository rackUnitUsageRepository;

    @Override
    @Cacheable(value = "countOfModels")
    public long countOfModels() {
        return this.modelRepository.count();
    }

    @Override
    @Cacheable(value = "countOfLocations")
    public long countOfLocations() {
        final List<LocationCiBean> list = this.locationService.getDeepLocationsByOne("P", 10000);
        return list.size();
    }

    @Override
    @Cacheable(value = "countOfSchemas")
    public long countOfSchemas() {
        final ParameterizedTypeReference<ResultDTO<Long>> typeRef =
                new ParameterizedTypeReference<ResultDTO<Long>>() {
                };
        final ResponseEntity<ResultDTO<Long>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + CmdbApi.countSchemaUrl, HttpMethod.GET, null, typeRef);

        if (null == response) {
            throw new UnitedException("调用CMDB服务异常");
        }
        final ResultDTO<Long> result = response.getBody();
        return result.getData();
    }

    @Override
    @Cacheable(value = "countOfAssets")
    public long countOfAssets() {
        final ParameterizedTypeReference<ResultDTO<Long>> typeRef =
                new ParameterizedTypeReference<ResultDTO<Long>>() {
                };
        final ResponseEntity<ResultDTO<Long>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + CmdbApi.countAssetUrl, HttpMethod.GET, null, typeRef);

        if (null == response) {
            throw new UnitedException("调用CMDB服务异常");
        }
        final ResultDTO<Long> result = response.getBody();
        return result.getData();
    }

    @Override
    @Cacheable(value = "countOfItAssets")
    public long countOfItAssets() {
        final ParameterizedTypeReference<ResultDTO<Long>> typeRef =
                new ParameterizedTypeReference<ResultDTO<Long>>() {
                };
        final ResponseEntity<ResultDTO<Long>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + CmdbApi.countItAssetUrl, HttpMethod.GET, null, typeRef);

        if (null == response) {
            throw new UnitedException("调用CMDB服务异常");
        }
        final ResultDTO<Long> result = response.getBody();
        return result.getData();
    }

    @Override
    @Cacheable(value = "countOfPdgs")
    public long countOfPdgs() {
        final ParameterizedTypeReference<ResultDTO<Long>> typeRef =
                new ParameterizedTypeReference<ResultDTO<Long>>() {
                };
        final ResponseEntity<ResultDTO<Long>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + CmdbApi.countPdgUrl, HttpMethod.GET, null, typeRef);

        if (null == response) {
            throw new UnitedException("调用CMDB服务异常");
        }
        final ResultDTO<Long> result = response.getBody();
        return result.getData();
    }

    @Override
    @Cacheable(cacheNames = "StatisticServiceRack", key = "#PosCode")
    public JSONObject rack(final String PosCode) {

        JSONObject dataJo = null;
        try {
            //机房 属性PlanRackCount 规划机柜数
            final List<LocationCiBean> matchRoom = this.getMatchRoom(PosCode);
            //规划机柜数
            final List<LocationCiBean> usedToComputeRackCountRooms =
                    matchRoom.stream().filter(x -> x.getAttrs().stream()
                            .anyMatch(s -> "sub_location_type".equals(s.getKey())
                                    && "ROOM_IT".equals(s.getValue().toString())))
                            .collect(Collectors.toList());
            int PlanRackCount = 0;
            for (final LocationCiBean room : usedToComputeRackCountRooms) {
                for (final AttrBean a : room.getAttrs()) {
                    if (a.getKey().equals("PlanRackCount")) {
                        PlanRackCount += a.getValue() == null ? 0 : Integer.valueOf(a.getValue().toString());
                    }
                }
            }

            // 机柜
            final List<StandardCiBean> matchJG = this.getMatchJG(PosCode, 5);
            //装机机柜
            final int InstallRackCount = matchJG.size();
            int FreeRackCount = 0;
            int OccupyRackCount = 0;
            int PreoccupyRackCount = 0;
            for (final StandardCiBean r : matchJG) {
                final List<AttrBean> attrs = r.getAttrs();
                for (final AttrBean attr : attrs) {
                    if (attr.getKey().equals("leaseStatus")) {
                        final Object attrValue = attr.getValue();
                        if (null == attrValue) {
                            break;
                        }
                        if (attrValue.equals("1")) {
                            FreeRackCount++;
                        } else if (attrValue.equals("2")) {
                            OccupyRackCount++;
                        } else if (attrValue.equals("3")) {
                            PreoccupyRackCount++;
                        }
                    }
                }
            }

            //保留三位小数
            double UseRate = 0.000;
            UseRate = InstallRackCount == 0 ? 0.000
                    : ((Double.valueOf(InstallRackCount - FreeRackCount)) / Double.valueOf(InstallRackCount));
            BigDecimal bd = new BigDecimal(String.valueOf(UseRate));
            bd = bd.setScale(3, BigDecimal.ROUND_HALF_UP);
            UseRate = bd.doubleValue();
            //
            final String data =
                    "{\"code\":\"P\",\"data\":[{\"code\":\"PlanRackCount\",\"name\":\"规划机位\",\"value\":300,\"unit\":\"\"},{\"code\":\"InstallRackCount\",\"name\":\"装机量\",\"value\":278,\"unit\":\"\"},{\"code\":\"FreeRackCount\",\"name\":\"空闲\",\"value\":197,\"unit\":\"\"},{\"code\":\"OccupyRackCount\",\"name\":\"占用\",\"value\":77,\"unit\":\"\"},{\"code\":\"PreoccupyRackCount\",\"name\":\"预占\",\"value\":4,\"unit\":\"\"},{\"code\":\"UseRate\",\"name\":\"使用率\",\"value\":0.291,\"unit\":\"\"}]}";
            dataJo = JSON.parseObject(data);
            dataJo.put("code", PosCode);
            for (final Object x : dataJo.getJSONArray("data")) {
                final JSONObject d = (JSONObject) x;
                if (d.getString("code").equals("PlanRackCount")) {
                    d.put("value", PlanRackCount);
                }
                if (d.getString("code").equals("InstallRackCount")) {
                    d.put("value", InstallRackCount);
                }
                if (d.getString("code").equals("FreeRackCount")) {
                    d.put("value", FreeRackCount);
                }
                if (d.getString("code").equals("OccupyRackCount")) {
                    d.put("value", OccupyRackCount);
                }
                if (d.getString("code").equals("PreoccupyRackCount")) {
                    d.put("value", PreoccupyRackCount);
                }
                if (d.getString("code").equals("UseRate")) {
                    d.put("value", UseRate);
                }
            }
        } catch (final Exception e) {
            StatisticServiceImpl.log.error("", e);
            return null;
        }

        return dataJo;
    }

    @Override
    @Cacheable(cacheNames = "StatisticServiceRackType", key = "#PosCode")
    public JSONObject rackType(final String PosCode) {
        JSONObject result = null;
        try {
            final String data =
                    "{\"groupData\":[{\"name\":\"政企业务\",\"serData\":[{\"tag\":\"政企业务\",\"value\":60}]},{\"name\":\"自有业务\",\"serData\":[{\"tag\":\"自有业务\",\"value\":20}]},{\"name\":\"网络机柜\",\"serData\":[{\"tag\":\"网络机柜\",\"value\":10}]},{\"name\":\"预留\",\"serData\":[{\"tag\":\"预留\",\"value\":5}]},{\"name\":\"电源柜\",\"serData\":[{\"tag\":\"电源柜\",\"value\":5}]},{\"name\":\"ODF柜\",\"serData\":[{\"tag\":\"ODF柜\",\"value\":5}]}]}";
            // 机柜
            final List<StandardCiBean> matchJG = this.getMatchJG(PosCode, 5);
            int zqyw = 0;
            int zyyw = 0;
            int wljg = 0;
            int dyg = 0;
            int odfg = 0;
            int yl = 0;

            for (final StandardCiBean r : matchJG) {
                final List<AttrBean> attrs = r.getAttrs();
                for (final AttrBean attr : attrs) {
                    if (attr.getKey().equals("rackType")) {
                        final Object attrValue = attr.getValue();
                        if (null == attrValue) {
                            break;
                        }
                        if (attrValue.equals("1")) {
                            zqyw++;
                            break;
                        } else if (attrValue.equals("2")) {
                            zyyw++;
                            break;
                        } else if (attrValue.equals("3")) {
                            wljg++;
                            break;
                        } else if (attrValue.equals("4")) {
                            dyg++;
                            break;
                        } else if (attrValue.equals("5")) {
                            odfg++;
                            break;
                        } else if (attrValue.equals("6")) {
                            yl++;
                            break;
                        }
                    }
                }
            }
            result = JSON.parseObject(data);
            final JSONArray groupArray = result.getJSONArray("groupData");
            for (final Object groupO : groupArray) {
                final JSONObject groupJo = (JSONObject) groupO;
                final JSONObject serDataJo = groupJo.getJSONArray("serData").getJSONObject(0);
                if (serDataJo.getString("tag").equals(RackTypeStatus.zqyw.getDesc())) {
                    serDataJo.put("value", zqyw);
                } else if (serDataJo.getString("tag").equals(RackTypeStatus.zyyw.getDesc())) {
                    serDataJo.put("value", zyyw);
                } else if (serDataJo.getString("tag").equals(RackTypeStatus.wljg.getDesc())) {
                    serDataJo.put("value", wljg);
                } else if (serDataJo.getString("tag").equals(RackTypeStatus.dyg.getDesc())) {
                    serDataJo.put("value", dyg);
                } else if (serDataJo.getString("tag").equals(RackTypeStatus.odfg.getDesc())) {
                    serDataJo.put("value", odfg);
                } else if (serDataJo.getString("tag").equals(RackTypeStatus.yl.getDesc())) {
                    serDataJo.put("value", yl);
                }
            }
        } catch (final Exception e) {
            StatisticServiceImpl.log.error("", e);
            return null;
        }
        return result;
    }

    @Override
    public JSONObject u(final String PosCode) {

        if (this.cacheService.isInCache(CmdbSynConstants.LOCATION_U_CACHE_NAME, PosCode)) {
            final Object cacheData =
                    this.cacheService.get(CmdbSynConstants.LOCATION_U_CACHE_NAME, PosCode);
            return (JSONObject) cacheData;
        }
        return null;
    }

    @Override
    public JSONObject netflow(final String PosCode) {

        if (this.cacheService.isInCache(CmdbSynConstants.FLOW_CACHE_NAME, PosCode)) {
            final Object cacheData =
                    this.cacheService.get(CmdbSynConstants.FLOW_CACHE_NAME, PosCode);
            return (JSONObject) cacheData;
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    @Cacheable(cacheNames = "StatisticServiceLBKpi", key = "#posCode")
    public JSONArray getLBKpi(final String posCode) {
        if (StringUtils.isBlank(posCode)) {
            return null;
        }
        final String data =
                "[{\"code\":\"rackCount\",\"name\":\"机柜数量\",\"value\":0},{\"code\":\"uCount\",\"name\":\"U位数量\",\"value\":0},{\"code\":\"customCount\",\"name\":\"客户数量\",\"value\":0},{\"code\":\"indentCount\",\"name\":\"业务数量\",\"value\":0}]";
        final Map<String, Object> matchJGMap = this.getMatchJGMap(posCode, 2);
        final List<String> rackCodes = (List<String>) matchJGMap.get("listCodes");
        final JSONArray result = JSON.parseArray(data);
        if (rackCodes.isEmpty()) {
            return result;
        }
        final List<RackUnitUsage> listUUsed = this.rackUnitUsageRepository.findByRackCodeIn(rackCodes);
        final int rackCount = rackCodes.size();
        final int uCount = this.getUCount(posCode);
        final int customCount = listUUsed.stream().filter(u -> !u.getCustCode().isEmpty())
                .collect(Collectors.groupingBy(RackUnitUsage::getCustCode)).size();
        final int indentCount = listUUsed.stream().filter(u -> !u.getIndentCode().isEmpty())
                .collect(Collectors.groupingBy(RackUnitUsage::getIndentCode)).size();
        for (final Object o : result) {
            final JSONObject jo = (JSONObject) o;
            if (jo.getString("code").equals("rackCount")) {
                jo.put("value", rackCount);
            } else if (jo.getString("code").equals("uCount")) {
                jo.put("value", uCount);
            } else if (jo.getString("code").equals("customCount")) {
                jo.put("value", customCount);
            } else if (jo.getString("code").equals("indentCount")) {
                jo.put("value", indentCount);
            }
        }
        return result;
    }

    @Override
    @Cacheable(cacheNames = "StatisticServiceLBRackStatus", key = "#posCode")
    public JSONArray getLBRackStatus(final String posCode) {
        if (StringUtils.isBlank(posCode)) {
            return null;
        }
        final String data =
                "[{\"code\":\"OccupyRackCount\",\"name\":\"占用\",\"value\":0},{\"code\":\"PreoccupyRackCount\",\"name\":\"预占\",\"value\":0},{\"code\":\"FreeRackCount\",\"name\":\"空闲\",\"value\":0}]";
        final List<StandardCiBean> matchJG = this.getMatchJG(posCode, 5);
        final JSONArray result = JSON.parseArray(data);
        if (matchJG.isEmpty()) {
            return result;
        }

        int FreeRackCount = 0;
        int OccupyRackCount = 0;
        int PreoccupyRackCount = 0;
        for (final StandardCiBean r : matchJG) {
            final List<AttrBean> attrs = r.getAttrs();
            for (final AttrBean attr : attrs) {
                if (attr.getKey().equals("leaseStatus")) {
                    final Object attrValue = attr.getValue();
                    if (null == attrValue) {
                        break;
                    }
                    if (attrValue.equals("1")) {
                        FreeRackCount++;
                    } else if (attrValue.equals("2")) {
                        OccupyRackCount++;
                    } else if (attrValue.equals("3")) {
                        PreoccupyRackCount++;
                    }
                }
            }
        }

        for (final Object x : result) {
            final JSONObject d = (JSONObject) x;

            if (d.getString("code").equals("FreeRackCount")) {
                d.put("value", FreeRackCount);
            }
            if (d.getString("code").equals("OccupyRackCount")) {
                d.put("value", OccupyRackCount);
            }
            if (d.getString("code").equals("PreoccupyRackCount")) {
                d.put("value", PreoccupyRackCount);
            }

        }

        return result;
    }

    @Override
    @Cacheable(cacheNames = "StatisticServiceLBUStatus", key = "#posCode")
    public JSONArray getLBUStatus(final String posCode) {
        if (StringUtils.isBlank(posCode)) {
            return null;
        }
        final String data =
                "[{\"code\":\"used\",\"name\":\"使用\",\"value\":0},{\"code\":\"empty\",\"name\":\"空闲\",\"value\":0}]";
        final JSONArray result = JSON.parseArray(data);
        int used = 0;
        int empty = 0;

        if (this.cacheService.isInCache(CmdbSynConstants.LOCATION_U_CACHE_NAME, posCode)) {
            final Object cacheData =
                    this.cacheService.get(CmdbSynConstants.LOCATION_U_CACHE_NAME, posCode);
            final JSONObject jo = (JSONObject) cacheData;
            final JSONArray ja = jo.getJSONArray("data");
            for (final Object o : ja) {
                final JSONObject jox = (JSONObject) o;
                if (jox.getString("code").equals("used")) {
                    used = Integer.valueOf(jox.getString("value"));
                } else if (jox.getString("code").equals("empty")) {
                    empty = Integer.valueOf(jox.getString("value"));
                }

            }

        }
        for (final Object x : result) {
            final JSONObject d = (JSONObject) x;

            if (d.getString("code").equals("used")) {
                d.put("value", used);
            }
            if (d.getString("code").equals("empty")) {
                d.put("value", empty);
            }

        }
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    @Cacheable(cacheNames = "StatisticServiceLBCustoms", key = "#posCode")
    public JSONArray getLBCustoms(final String posCode) {
        if (StringUtils.isBlank(posCode)) {
            return null;
        }

        final Map<String, Object> matchJGMap = this.getMatchJGMap(posCode, 2);
        final List<String> rackCodes = (List<String>) matchJGMap.get("listCodes");
        if (rackCodes.isEmpty()) {
            return null;
        }
        final List<RackUnitUsage> listUUsed = this.rackUnitUsageRepository.findByRackCodeIn(rackCodes);

        final Map<String, List<RackUnitUsage>> CustMap =
                listUUsed.stream().filter(u -> !u.getCustCode().isEmpty())
                        .collect(Collectors.groupingBy(RackUnitUsage::getCustCode));
        final JSONArray result = new JSONArray();
        CustMap.entrySet().forEach(x -> {
            final JSONObject a = new JSONObject();
            a.put("custCode", x.getKey());
            a.put("custName", x.getValue().get(0).getCustName());
            result.add(a);
        });
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    @Cacheable(cacheNames = "StatisticServiceLBIndents", key = "#posCode")
    public JSONArray getLBIndents(final String posCode) {
        if (StringUtils.isBlank(posCode)) {
            return null;
        }

        final Map<String, Object> matchJGMap = this.getMatchJGMap(posCode, 2);
        final List<String> rackCodes = (List<String>) matchJGMap.get("listCodes");
        if (rackCodes.isEmpty()) {
            return null;
        }
        final List<RackUnitUsage> listUUsed = this.rackUnitUsageRepository.findByRackCodeIn(rackCodes);

        final Map<String, List<RackUnitUsage>> CustMap =
                listUUsed.stream().filter(u -> !u.getIndentCode().isEmpty())
                        .collect(Collectors.groupingBy(RackUnitUsage::getIndentCode));
        final JSONArray result = new JSONArray();
        CustMap.entrySet().forEach(x -> {
            final JSONObject a = new JSONObject();
            a.put("indentCode", x.getKey());
            a.put("indentName", x.getValue().get(0).getIndentName());
            result.add(a);
        });
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    @Cacheable(cacheNames = "StatisticServiceLBDetail", key = "#posCode")
    public JSONArray getLBDetail(final String posCode) {
        if (StringUtils.isBlank(posCode)) {
            return null;
        }

        final Map<String, Object> matchJGMap = this.getMatchJGMap(posCode, 2);
        final List<String> rackCodes = (List<String>) matchJGMap.get("listCodes");
        final Map<String, String> nameAndCodeMap = (Map<String, String>) matchJGMap.get("nameAndCodeMap");
        if (rackCodes.isEmpty()) {
            return null;
        }
        final List<RackUnitUsage> listUUsed = this.rackUnitUsageRepository.findByRackCodeIn(rackCodes);
        final Map<String, List<RackUnitUsage>> ruUsageMap =
                listUUsed.stream().collect(Collectors.groupingBy(RackUnitUsage::getRackCode));
        final JSONArray result = new JSONArray();
        ruUsageMap.entrySet().forEach(x -> {
            final JSONObject jo = new JSONObject();
            jo.put("rackCode", nameAndCodeMap.get(x.getKey()));
            final JSONArray ulist = new JSONArray();
            x.getValue().forEach(v -> {
                final JSONObject item = new JSONObject();
                item.put("startU", v.getStartUnit());
                item.put("endU", v.getEndUnit());
                item.put("indentCode", v.getIndentCode());
                item.put("custCode", v.getCustCode());
                ulist.add(item);
            });

            jo.put("uList", ulist);
            result.add(jo);
        });
        return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    @Cacheable(cacheNames = "StatisticServiceLBCustAndIndent", key = "#posCode+#rackTypeName")
    public JSONArray getLBCustAndIndent(final String posCode, final String rackTypeName) {
        final String data =
                "[{\"code\":\"CustomCount\",\"name\":\"客户数\",\"value\":0},{\"code\":\"IndentCount\",\"name\":\"业务量\",\"value\":0}]";
        final JSONArray result = JSON.parseArray(data);
        int customCount = 0;
        int indentCount = 0;

        if (StringUtils.isBlank(posCode)) {
            return null;
        }
        List<String> rackCodes = null;
        if (StringUtils.isEmpty(rackTypeName)) {
            //不指定业务类型查询所有类型
            final Map<String, Object> matchJGMap = this.getMatchJGMap(posCode, 5);
            rackCodes = (List<String>) matchJGMap.get("listCodes");
        } else {
            final String rackTypeValue = this.getrackTypeValueByName(rackTypeName);
            final List<StandardCiBean> matchJG = this.getMatchJG(posCode, 5);
            rackCodes = matchJG.stream()
                    .filter(x -> x.getAttrs().stream()
                            .anyMatch(s -> s.getKey().equals("rackType") && s.getValue().equals(rackTypeValue)))
                    .map(n -> n.getName()).collect(Collectors.toList());

        }
        final List<RackUnitUsage> listUUsed = this.rackUnitUsageRepository.findByRackCodeIn(rackCodes);
        customCount = listUUsed.stream().filter(x -> !x.getCustCode().isEmpty())
                .collect(Collectors.groupingBy(RackUnitUsage::getCustCode)).size();

        indentCount = listUUsed.stream().filter(x -> !x.getIndentCode().isEmpty())
                .collect(Collectors.groupingBy(RackUnitUsage::getIndentCode)).size();
        for (final Object x : result) {
            final JSONObject d = (JSONObject) x;

            if (d.getString("code").equals("CustomCount")) {
                d.put("value", customCount);
            }
            if (d.getString("code").equals("IndentCount")) {
                d.put("value", indentCount);
            }

        }
        return result;
    }

    private Map<String, Object> getMatchJGMap(final String posCode, final int deep) {
        final Map<String, Object> result = new HashMap<>();
        final List<String> listJg = new ArrayList<>();
        final Map<String, String> nameAndCodeMap = new HashMap<>();
        // 获取定制层，机房下柜列集合
        List<LocationCiBean> deepLocationsByOne = this.locationService.getDeepLocationsByOne(posCode, deep);
        deepLocationsByOne =
                deepLocationsByOne.stream().filter(x -> x.getAttrs().stream().anyMatch(s -> "LIE".equals(s.getValue())))
                        .collect(Collectors.toList());
        deepLocationsByOne.forEach(item -> {
            final List<StandardCiBean> allCiByForeignInst =
                    this.cmdbMicroService.getAllCiByCatetoriesAndForeign("CT_RACK", "location",
                            item.getCode());
            allCiByForeignInst.forEach(x -> {
                final AttrBean assetNumberBean = x.getAttrs().stream()
                        .filter(it -> "assetNumber".equalsIgnoreCase(it.getKey())).findAny().orElse(null);
                if (null != assetNumberBean) {
                    listJg.add((String) assetNumberBean.getValue());
                    nameAndCodeMap.put((String) assetNumberBean.getValue(), x.getCode());
                }
            });
        });

        StatisticServiceImpl.log.info("机房/楼层 {} 下机柜个数为 {} ", posCode, listJg.size());
        if (StatisticServiceImpl.log.isDebugEnabled()) {
            StatisticServiceImpl.log.debug("机柜 {} ", String.join(",", listJg));
        }
        result.put("listCodes", listJg);
        result.put("nameAndCodeMap", nameAndCodeMap);
        return result;

    }

    private List<StandardCiBean> getMatchJG(final String PosCode, final int deep) {
        //数据中心-机楼-层-房间-列-机柜
        //子类型属性sub_location_type：PARK-BUILD-ROOM-FLOOR-LIE
        final List<StandardCiBean> allMatchJG = new ArrayList<>();
        List<LocationCiBean> deepLocationsByOne = this.locationService.getDeepLocationsByOne(PosCode, deep);
        deepLocationsByOne =
                deepLocationsByOne.stream().filter(x -> x.getAttrs().stream().anyMatch(s -> "LIE".equals(s.getValue())))
                        .collect(Collectors.toList());
        deepLocationsByOne.forEach(item -> {
            final List<StandardCiBean> itemCiByForeignInst =
                    this.cmdbMicroService.getAllCiByCatetoriesAndForeign("CT_RACK", "location",
                            item.getCode());
            allMatchJG.addAll(itemCiByForeignInst);
        });

        return allMatchJG;

    }

    public List<LocationCiBean> getMatchRoom(final String PosCode) {
        //数据中心-机楼-层-房间-列-机柜
        //子类型属性sub_location_type：PARK-BUILD-ROOM-FLOOR-LIE

        List<LocationCiBean> deepLocationsByOne = this.locationService.getDeepLocationsByOne(PosCode, 5);
        deepLocationsByOne =
                deepLocationsByOne
                        .stream().filter(
                                x -> x.getAttrs().stream()
                                        .anyMatch(s -> s.getKey().equals("sub_location_type")
                                                && s.getValue().toString().contains("ROOM")))
                        .collect(Collectors.toList());

        return deepLocationsByOne;

    }

    private int getUCount(final String PosCode) {
        if (this.cacheService.isInCache(CmdbSynConstants.LOCATION_U_CACHE_NAME, PosCode)) {
            final Object cacheData =
                    this.cacheService.get(CmdbSynConstants.LOCATION_U_CACHE_NAME, PosCode);
            final JSONObject jo = (JSONObject) cacheData;
            final JSONArray ja = jo.getJSONArray("data");
            for (final Object o : ja) {
                final JSONObject jox = (JSONObject) o;
                if (jox.getString("code").equals("total")) {
                    return jox.getString("value").isEmpty() ? 0 : Integer.valueOf(jox.getString("value"));
                }

            }
        }
        return 0;
    }

    private String getrackTypeValueByName(final String rackTypeName) {
        final RackTypeStatus[] values = RackTypeStatus.values();
        for (final RackTypeStatus rackTypeStatus : values) {
            if (rackTypeStatus.getDesc().equals(rackTypeName)) {
                return rackTypeStatus.getValue();
            }
        }
        return rackTypeName;
    }

}
